package cn.hpclub.server.controller.admin;

import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.RandomStringUtils;

import com.jfinal.aop.Before;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.tx.Tx;

import cn.hpclub.server.constant.Constant;
import cn.hpclub.server.model.Organization;
import cn.hpclub.server.model.SysRole;
import cn.hpclub.server.model.SysUser;
import cn.hpclub.server.model.SysUserRole;
import cn.hpclub.server.service.AccountService;
import cn.hpclub.server.util.Base64Utils;
import cn.hpclub.server.util.DESAS;
import cn.hpclub.server.util.DESCrypto;
import cn.hpclub.server.util.InterfaceUtil;
import cn.hpclub.server.util.RSAUtils;

/**
 * 后台类 - 账户管理
 * 
 */
public class AccountController extends BaseAdminController<SysUser>{

    static int UI_PAGER_NUMBER_DEFAULT = 1;                                                      // UI默认起始页
    static int UI_PAGER_SIZE_DEFAULT   = 10;                                                     // UI页容量

    private static final String ORG_LIST    = "orgList";
    private static final String ORG_ID      = "org_id";

    String     select                  = "select *";
    String     sqlExceptSelect         = "from " + getModelClass().getSimpleName().toLowerCase();

    private void getRoles(){
        List<SysRole> roles = SysRole.dao.getActiveRoleListByLevel();
        setAttr("roles", roles);
    }

    @Override
    public void findByPage(String db){
        String select = "select j.DisplayName as orgName,r.name as roleName,u.*";
        String sqlExceptSelect = "from sys_user u left join organization j on j.id=u.org_id left join sys_user_role ur on ur.user_id=u.id left join sys_role r on r.id=ur.role_id";
        ConcurrentHashMap<String, String> searchInfo = getSearchInfo();
        String name = getMyParam(searchInfo);
        Page<SysUser> pager;

        sqlExceptSelect += " where j.id in "
                + InterfaceUtil.getChlidOrgIdSql(InterfaceUtil.getOrgId(), Constant.MAX_ORG_LEVEL, true);

        if(StrKit.notBlank(name)){
            sqlExceptSelect += " and (u.real_name like ? or u.user_name like ?)";
            String para = "%" + name + "%";
            pager = getModel(SysUser.class).paginate(getParaToInt("pageNumber", 1), getParaToInt("pageSize", 10),
                                                     select, sqlExceptSelect, para, para);
        } else{
            pager = getModel(SysUser.class).paginate(getParaToInt("pageNumber", 1), getParaToInt("pageSize", 10),
                                                     select, sqlExceptSelect);
        }
        setAttr("pager", pager);
    }

    private String getOrgName(Integer orgId){
        String result = "";
        if(orgId != null){
            Organization org = Organization.dao.findById(orgId);
            result = org.getStr("DisplayName");
        }
        return result;
    }

    public void add(){
        setAttr("SysUser", new SysUser());
        genRSAKeyPair();
        getRoles();
        render("/admin/account_add.tpl");
    }

    @Before({ Tx.class })
    public void save(){
        String userName = getPara("user_name", "");
        if(StrKit.isBlank(userName)){
            this.setAttr("errorMessage", "亲,用户名不能为空");
            render("/common/error.tpl");
            return;
        }
        if(validateIsUserExist(userName)){
            this.setAttr("errorMessage", "亲,该账号已经存在");
            render("/common/error.tpl");
            return;
        }
        modalBind(true);
        redirect("/account/list");
    }

    // 判断是否已经存在用户名了
    private boolean validateIsUserExist(String userName){
        return Db.queryLong("SELECT COUNT(1) from sys_user WHERE user_name = ?", userName) > 0;
    }

    public void validate(){
        String userName = getPara("name", "");
        if(StrKit.notBlank(userName)){
            // 不存在此用户
            if(!validateIsUserExist(userName)){
                ajaxJsonSuccessMessage("");
                return;
            }
        }
        ajaxJsonErrorMessage("");
    }

    @Before({ Tx.class })
    public void update(){
        modalBind(false);
        redirect("/account/list");
    }

    private SysUser modalBind(boolean isAdd){
        SysUser sysUser = new SysUser();
        Integer id = getParaToInt("id", null);
        Integer is_lock = getParaToInt("isAccountEnabled", 0);
        String user_name = getPara("user_name", "");
        String password = getPara("password", "");
        String real_name = getPara("real_name", "");
        String telephone = getPara("telephone", "");
        String email = getPara("email", "");
        Integer org_id = getParaToInt("org_id", null);
        Integer role_id = getParaToInt("role_id", null);
        sysUser.set("id", id).set("isAccountEnabled", is_lock).set("real_name", real_name).set("telephone", telephone)
                .set("email", email).set("org_id", org_id);
        Date now = new Date();

        if(isAdd){
            String salt = RandomStringUtils.randomAlphanumeric(6).toUpperCase();
            String newPassword = "";
            try{
                /* RSA 解密 */
                String privateKey = this.getSessionAttr(Constant.PRIVATEKEY);
                String pwdByRSA = new String(RSAUtils.decryptByPrivateKey(Base64Utils.decode(password), privateKey));

                newPassword = DESCrypto.encryptPassword(pwdByRSA, salt);
            }
            catch(Exception e){
                e.printStackTrace();
            }

            sysUser.set("created_by", InterfaceUtil.getAdminId()).set("created_time", now).set("user_name", user_name)
                    .set("password", newPassword).set("salt", salt);
            sysUser.save();
            SysUserRole userRole = new SysUserRole();
            userRole.set("user_id", sysUser.get("id")).set("role_id", role_id)
                    .set("created_by", InterfaceUtil.getAdminId()).set("created_time", now);
            userRole.save();
        } else{
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String curTime = sdf.format(now);

            Db.update("update sys_user_role set role_id=?, last_updated_by= " + InterfaceUtil.getAdminId()
                    + " ,last_updated_time='" + curTime + "' where user_id=?", role_id, sysUser.getInt("id"));

            sysUser.set("last_updated_time", now).set("last_updated_by", InterfaceUtil.getAdminId());
            sysUser.update();
        }
        return sysUser;
    }

    // 编辑
    public void edit(){
        String id = getPara(SysUser.ID);
        String decryptId = "0";
        try{
            decryptId = new DESAS().decrypt(id);
            Record r = SysUser.dao.getUser(Integer.parseInt(decryptId));
            setAttr("SysUser", r);
            setAttr("orgName", r.getStr("orgName"));
            setAttr("roleId", r.getInt("roleId"));
            setAttr("roleName", r.getStr("roleName"));
            setAttr("roles", SysRole.dao.getActiveRoleListByLevel());

            genRSAKeyPair();
            render("/admin/account_add.tpl");
        }
        catch(Exception e){
            e.printStackTrace();
            renderError(500);
        }
    }

    public void password(){
        SysUser user = SysUser.dao.findById(InterfaceUtil.getAdminId());
        try{
            user.set(SysUser.ID, AccountService.service.encryptId(user.getInt(SysUser.ID) + ""));
        }
        catch(Exception e){
            e.printStackTrace();
        }
        setAttr("SysUser", user);
        genRSAKeyPair();
        render("/admin/account_password.tpl");

    }

    public void validatePassword(){
        String id = getPara("id", "");
        String password = getPara("password", "");
        SysUser sysUser;
        if(StrKit.notBlank(id) && StrKit.notBlank(password)){
            sysUser = SysUser.dao.findById(id);
            password = DigestUtils.md5Hex(password);
            if(password.equals(sysUser.get("password"))){
                ajaxJsonSuccessMessage("");
                return;
            }
        }
        ajaxJsonErrorMessage("");
    }

    @Before({ Tx.class })
    public void updatePassword(){
        try{
            AccountService.service.updatePassword(getPara(SysUser.ID, ""), getPara(SysUser.PASSWORD, ""),
                                                  getPara("newPassword", ""), this.getSessionAttr(Constant.PRIVATEKEY));
            ajaxJsonSuccessMessage("密码修改成功，请使用新密码登录");
        }
        catch(Exception e){
            ajaxJsonErrorMessage(e.getMessage());
        }
    }

    @Before({ Tx.class })
    public void resetPassword(){

        String id = getPara(SysUser.ID, "");
        if(AccountService.service.resetPassword(id)){
            redirect("/account/list");

        } else{
            this.setAttr("errorMessage", "亲,重置密码错误");
            render("/common/error.tpl");
        }
    }

    public void list(){
        int defaultOrgId = iniOrgTree();
        ConcurrentHashMap<String, String> searchInfo = getSearchInfo();
        if(searchInfo.get(ORG_ID) == null){
            searchInfo.put(ORG_ID, String.valueOf(defaultOrgId));
        }
        setAttr("pager", SysUser.dao.list(getParaToInt(Constant.Ui.PAGER_NUMBER, 1),
                                          getParaToInt(Constant.Ui.PAGER_SIZE, 10), searchInfo));
        setAttrs(searchInfo);
        render("/admin/account.tpl");
    }

    private int iniOrgTree(){
        List<Entry<String, String>> orgList = InterfaceUtil.getOrgList();
        setAttr(ORG_LIST, orgList);
        if(orgList.size() > 0){
            return Integer.parseInt(orgList.get(0).getValue());
        } else{
            return 0;
        }
    }


    /**
     * @Title: getParam
     * @Description:TODO
     * @param searchInfo
     * @return String
     */
    private String getMyParam(ConcurrentHashMap<String, String> searchInfo){
        String keyword = "";
        for(Entry<String, String> item : searchInfo.entrySet()){
            if("name".equals(item.getKey())){
                keyword = item.getValue();
            }
        }

        return keyword;
    }

    // 删除
    @Before({ Tx.class })
    public void delete() throws SQLException{
        Object[] result = AccountService.service.delete(getParaValues("ids"));
        if(((boolean)result[0])){
            ajaxJsonSuccessMessage((String)result[1]);
        } else{

            ajaxJsonErrorMessage((String)result[1]);
        }
    }
}
